`timescale 1ns/100ps
module tb();
//除法器位宽
parameter DIV_WIDTH = 8;

//除法器连线
logic clk;
logic rst_n;
logic [DIV_WIDTH-1:0] su_dived_i;
logic [DIV_WIDTH-1:0] su_divor_i;
logic div_in_valid;
logic div_in_ready;
logic signed_en;
logic [DIV_WIDTH-1:0] div_res_data;
logic [DIV_WIDTH-1:0] div_rem_data;
logic div_out_valid;
logic div_out_ready;

//除法自测试
//hp_int_div_test(XXX,YYY,S);
//XXX: 被除数
//YYY: 除数
//  S: 有符号使能
initial begin
	div_out_ready = 0;
	adcrst();
	hp_int_div_test(11,2,0);
	hp_int_div_test(11,2,1);
	hp_int_div_test(11,2,1);
	hp_int_div_test(5,0,0);
	hp_int_div_test(5,0,0);
	hp_int_div_test(11,2,1);
	hp_int_div_test(21,3,0);
	hp_int_div_test(5,0,0);
	hp_int_div_test(-20,6,1);
	hp_int_div_test(-11,2,1);
	hp_int_div_test(11,-2,1);
	hp_int_div_test(-11,-2,1);
	hp_int_div_test(-128,-1,1);
	hp_int_div_test(-5,0,1);
	hp_int_div_test(5,0,0);
	hp_int_div_test(255,1,0);
	hp_int_div_test(255,1,0);
	#10;
	$stop;
end

// clk
initial begin
	clk = '0;
	forever #(0.5) clk = ~clk;
end

//复位任务adcrst();
task adcrst;
	rst_n <= '0;
	#10
	rst_n <= '1;
	#5;
endtask : adcrst

//除法自测试
//hp_int_div_test(XXX,YYY,S);
//XXX: 被除数
//YYY: 除数
//  S: 有符号使能
task hp_int_div_test;
	input [DIV_WIDTH-1:0] gen_dived;
	input [DIV_WIDTH-1:0] gen_divor;
	input gen_signed;
	//除法计算过程
	logic [DIV_WIDTH-1:0] gen_res;
	logic [DIV_WIDTH-1:0] gen_rem;
	logic div_err_flg;
	begin
		wait(div_in_ready);
		if (gen_signed) begin
			gen_res = $signed(gen_dived) / $signed(gen_divor);
			gen_rem = $signed(gen_dived) % $signed(gen_divor);
		end
		else begin
			gen_res = gen_dived / gen_divor;
			gen_rem = gen_dived % gen_divor;
		end
		div_out_ready = 0;
		su_dived_i = gen_dived;
		su_divor_i = gen_divor;
		signed_en = gen_signed;
		div_in_valid = 1;
		wait(~div_in_ready)
		su_dived_i = 0;
		su_divor_i = 0;
		signed_en = 0;
		div_in_valid = 0;
		wait(div_out_valid);
		div_out_ready = 1;
		wait(~div_out_valid);
		div_out_ready = 0;
		if(gen_res!=div_res_data || gen_rem!=div_rem_data) begin
			if(gen_signed) begin
				$display("dived =%d ,divor =%d,", $signed(gen_dived), $signed(gen_divor));
				$display(" signed int, Error!\n div res =%d, sys res =%d \n div rem =%d, sys rem =%d \n", $signed(div_res_data), $signed(gen_res), $signed(div_rem_data), $signed(gen_rem));
			end
			else begin
				$display("dived =%d ,divor =%d,", gen_dived, gen_divor);
				$display(" unsigned int, Error!\n div res =%d, sys res =%d \n div rem =%d, sys rem =%d \n",div_res_data, gen_res, div_rem_data, gen_rem);
			end
			$stop;
		end
		else begin
			if(gen_signed) begin
				$display("dived =%d ,divor =%d, signed int, div res =%d, div rem =%d, pass \n", $signed(gen_dived), $signed(gen_divor), $signed(div_res_data), $signed(div_rem_data));
			end
			else begin
				$display("dived =%d ,divor =%d, unsigned int, div res =%d, div rem =%d, pass \n", gen_dived, gen_divor, div_res_data, div_rem_data);
			end
		end

	end
	
endtask : hp_int_div_test


hp_int_div #(
	.DIV_WIDTH(DIV_WIDTH)
) inst_hp_int_div (
	.clk           (clk),
	.rst_n         (rst_n),
	.su_dived_i    (su_dived_i),
	.su_divor_i    (su_divor_i),
	.signed_en     (signed_en),
	.div_in_valid  (div_in_valid),
	.div_in_ready  (div_in_ready),
	.div_res_data  (div_res_data),
	.div_rem_data  (div_rem_data),
	.div_out_valid (div_out_valid),
	.div_out_ready (div_out_ready)
);


// 输出波形
initial begin
	$dumpfile("tb.lxt");  //生成lxt的文件名称
	$dumpvars(0, tb);   //tb中实例化的仿真目标实例名称
end

endmodule
